package experiment1;

import java.util.Random;

public class RastriginFunc {

    // Rastrigin函数计算
    public static double rastrigin(double x1, double x2) {
        return 20 + x1 * x1 + x2 * x2 - 10 * (Math.cos(2 * Math.PI * x1) + Math.cos(2 * Math.PI * x2));
    }

    // 粒子类
    static class Particle {
        double x1, x2; // 粒子位置
        double v1, v2; // 粒子速度
        double pbestX1, pbestX2; // 粒子的历史最佳位置
        double pbestValue; // 粒子历史最佳值

        public Particle() {
            Random rand = new Random();
            // 初始化粒子的位置和速度
            this.x1 = rand.nextDouble() * 10 - 5;  // 随机值在[-5, 5]之间
            this.x2 = rand.nextDouble() * 10 - 5;
            this.v1 = rand.nextDouble() * 2 - 1;  // 随机速度
            this.v2 = rand.nextDouble() * 2 - 1;
            this.pbestX1 = this.x1;
            this.pbestX2 = this.x2;
            this.pbestValue = rastrigin(this.x1, this.x2);
        }

        // 更新粒子的位置和速度
        public void update(double gbestX1, double gbestX2, double w, double c1, double c2) {
            Random rand = new Random();
            // 更新速度
            this.v1 = w * this.v1 + c1 * rand.nextDouble() * (this.pbestX1 - this.x1) + c2 * rand.nextDouble() * (gbestX1 - this.x1);
            this.v2 = w * this.v2 + c1 * rand.nextDouble() * (this.pbestX2 - this.x2) + c2 * rand.nextDouble() * (gbestX2 - this.x2);

            // 更新位置
            this.x1 += this.v1;
            this.x2 += this.v2;

            // 计算新的函数值
            double currentValue = rastrigin(this.x1, this.x2);
            if (currentValue < this.pbestValue) {
                // 如果当前粒子的位置比历史最优解好，更新历史最优解
                this.pbestX1 = this.x1;
                this.pbestX2 = this.x2;
                this.pbestValue = currentValue;
            }
        }
    }

    public static void main(String[] args) {
        int swarmSize = 30; // 粒子群的大小
        int maxIterations = 10000; // 最大迭代次数
        double w = 0.5; // 惯性权重
        double c1 = 1.5; // 认知因子
        double c2 = 1.5; // 社会因子

        // 初始化粒子群
        Particle[] swarm = new Particle[swarmSize];
        for (int i = 0; i < swarmSize; i++) {
            swarm[i] = new Particle();
        }

        // 初始化全局最优解
        double gbestX1 = swarm[0].pbestX1;
        double gbestX2 = swarm[0].pbestX2;
        double gbestValue = swarm[0].pbestValue;

        // 迭代过程
        for (int iteration = 0; iteration < maxIterations; iteration++) {
            // 更新全局最优解
            for (Particle p : swarm) {
                if (p.pbestValue < gbestValue) {
                    gbestX1 = p.pbestX1;
                    gbestX2 = p.pbestX2;
                    gbestValue = p.pbestValue;
                }
            }

            // 更新粒子的位置和速度
            for (Particle p : swarm) {
                p.update(gbestX1, gbestX2, w, c1, c2);
            }

            // 输出每隔一定次数的迭代信息
            if (iteration % 100 == 0) {
                System.out.println("迭代次数 " + iteration + ": 最佳适应度 = " + gbestValue);
            }
        }

        // 输出最终的全局最优解
        System.out.println("找出最优解：");
        System.out.println("x1 = " + gbestX1 + ", x2 = " + gbestX2);
        System.out.println("最小值为：" + gbestValue);
    }
}

